import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

// Stack允许子组件堆叠，而Positioned用于根据Stack的四个角来确定子组件的位置。
// Stack:alignment：此参数决定如何去对齐没有定位（没有使用Positioned）或部分定位的子组件。所谓部分定位，在这里特指没有在某一个轴上定位：left、right为横轴，top、bottom为纵轴，只要包含某个轴上的一个定位属性就算在该轴上有定位。
// textDirection：和Row、Wrap的textDirection功能一样，都用于确定alignment对齐的参考系
// fit：此参数用于确定没有定位的子组件如何去适应Stack的大小。StackFit.loose表示使用子组件的大小，StackFit.expand表示扩伸到Stack的大小。
// overflow：此属性决定如何显示超出Stack显示空间的子组件；值为Overflow.clip时，超出部分会被剪裁（隐藏），值为Overflow.visible 时则不会。

// Positioned
// left、top 、right、 bottom分别代表离Stack左、上、右、底四边的距离。
// width、height 和其它地方的意义稍微有点区别，此处用于配合left、top 、right、 bottom来定位组件，举个例子，在水平方向时，你只能指定left、right、width三个属性中的两个，如指定left和width后，right会自动算出(left+width)，如果同时指定三个属性则会报错，垂直方向同理。

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text(title)),
        body: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Container(
              width: double.infinity,
              height: 200,
              color: Colors.cyan,
              child: Stack(
                alignment: Alignment.center, //指定未定位或部分定位widget的对齐方式
                children: <Widget>[
                  // 第一个没有指定定位，并且alignment值为Alignment.center，所以它会居中显示。
                  Container(
                    child: Text("Hello world",
                        style: TextStyle(color: Colors.white)),
                    color: Colors.red,
                  ),
                  // 第二个只指定了水平方向的定位(left)，所以属于部分定位，即垂直方向上没有定位，那么它在垂直方向的对齐方式则会按照alignment指定的对齐方式对齐，即垂直方向居中。
                  Positioned(
                    left: 18.0,
                    child: Text("I am Jack"),
                  ),
                  // 第三个子文本组件Text("Your friend")，和第二个Text原理一样，只不过是水平方向没有定位，则水平方向居中。
                  Positioned(
                    top: 28.0,
                    child: Text("Your friend"),
                  )
                ],
              ),
            ),
            Spacer(flex: 1),
            Container(
              width: double.infinity,
              height: 200,
              color: Colors.cyan,
              child: Stack(
                alignment: Alignment.center, //指定未定位或部分定位widget的对齐方式
                fit: StackFit.expand, //未定位widget占满Stack整个空间
                children: <Widget>[
                  // 第一个没有指定定位，因为StackFit.expand占满Stack整个空间，因为堆叠二三可以依次显示，如果和第二个元素换位置，则会遮盖当前第二个元素，但可以显示第三个。
                  Container(
                    child: Text("Hello world",
                        style: TextStyle(color: Colors.white)),
                    color: Colors.red,
                  ),
                  // 第二个只指定了水平方向的定位(left)，所以属于部分定位，即垂直方向上没有定位，那么它在垂直方向的对齐方式则会按照alignment指定的对齐方式对齐，即垂直方向居中。
                  Positioned(
                    left: 18.0,
                    child: Text("I am Jack"),
                  ),
                  // 第三个子文本组件Text("Your friend")，和第二个Text原理一样，只不过是水平方向没有定位，则水平方向居中。
                  Positioned(
                    top: 28.0,
                    child: Text("Your friend"),
                  )
                ],
              ),
            )
          ],
        ));
  }
}
